package br.edu.ufcg.dsc.adsd.lotv.core.entites;

import br.edu.ufcg.dsc.adsd.lotv.core.Connectable;
import br.edu.ufcg.dsc.adsd.lotv.core.LANPackage;
import br.edu.ufcg.dsc.adsd.lotv.utils.Constants;
import eduni.simjava.Sim_event;
import eduni.simjava.Sim_system;
import eduni.simjava.distributions.Sim_negexp_obj;

public class Printer extends Connectable {

	private Sim_negexp_obj delayer;
	private int countPrints = 0;

	public Printer(String name, double mean) {
		super(name);
		this.delayer = new Sim_negexp_obj(name + Constants.DISTRIBUTION_NAME, mean);
		this.add_generator(this.delayer);
	}
	
	/**
	 * Realizando a impressão e respondendo com o resultado
	 * @param info
	 */
	private void print(Sim_event info) {
		LANPackage inPkg = LANPackage.extract(info);
		LANPackage outPkg = new LANPackage(this.get_name(), inPkg.getSrc());
		outPkg.valueOf(Constants.PACKAGE_TYPE, Constants.OKAY_RESPONSE);
		this.sim_process(this.delayer.sample());
		this.sim_schedule(this.gatewayPort, 0.0, Constants.UNICAST, outPkg);
		this.countPrints++;
	}
	
	/**
	 * Anuncia para a rede que está ligada/operacional
	 */
	private void announce() {
		LANPackage pkg = new LANPackage(this.get_name(), null);
		pkg.valueOf(Constants.PACKAGE_TYPE, Constants.INSTALL_PRINTER);
		this.sim_process(this.delayer.sample());
		this.sim_schedule(this.gatewayPort, 0.0, Constants.BROADCAST, pkg);
	}
	
	@Override
	public void body() {
		System.out.println("Printer ID:" + this.get_id() + " - Ports: " + this.ports);
		this.announce();
		while(Sim_system.running()) {
			Sim_event e = new Sim_event();
			this.sim_get_next(e);
			LANPackage pkg = LANPackage.extract(e);
			/* POR ALGUMA RAZÃO ESTRANHA CHEGA UNS EVENTOS COM ID -1 E SEM LANPACKAGE
			 * isso tava quebrando
			 */
			if(e.get_src() >= 0) {
				int type = (Integer)pkg.valueOf(Constants.PACKAGE_TYPE);
				switch (type) {
				case Constants.FIND_PRINTER:
					this.announce();
					break;
				case Constants.PRINT_JOB:
					this.print(e);
				default:
					break;
				}
			}
			this.sim_completed(e);
		}
		System.out.println("TOTAL PRINTS: " + this.countPrints);
	}
	
}
